package eu.tolu.cableSpotter;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeMap;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import eu.tolu.cableSpotter.R;
import eu.tolu.cableSpotter.help.AppPreferences;
import eu.tolu.cableSpotter.help.MyLocation;
import eu.tolu.cableSpotter.help.SitesOverlay;
import eu.tolu.cableSpotter.help.MyLocation.LocationResult;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import android.graphics.Point;
import android.graphics.drawable.Drawable;

public class GmapLocalView extends MapActivity {
	public Location myLocation;
	private GeoPoint myGeoPoint;
	private List<Overlay> listOfOverlays;
	private MapView myMapView;
	private MapController myMapController;
	int cableCount = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.gmap_local_view);

		final Bundle extras = getIntent().getExtras();

		if (extras != null) {
			this.cableCount = Integer.parseInt(extras.getString("cableCount"));
			System.out.println("Anzahl: " + extras.getString("cableCount"));
		}
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		if(myLocation == null)
			getLocation();
	}

	private void getLocation() {
		LocationResult locationResult = new LocationResult() {
			@Override
			public void gotLocation(Location location) {
				if (location != null) {
					setMyLocation(location);

				} else {
					System.out.println("no location found");
				}
			}
		};

		MyLocation myLocation = new MyLocation();
		if (!myLocation.getLocation(this, locationResult)) {
			DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					switch (which) {
					case DialogInterface.BUTTON_POSITIVE:
						// Yes button clicked
						Intent gpsOptionsIntent = new Intent(
								android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
						startActivity(gpsOptionsIntent);

					case DialogInterface.BUTTON_NEGATIVE:
						// No button clicked
						break;
					}
				}
			};

			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Activate GPS or Networklocation?")
					.setPositiveButton("Yes", dialogClickListener)
					.setNegativeButton("No", dialogClickListener).show();
		}
	}

	private void setMyLocation(Location location) {
		GeoPoint gp = null;
		gp = new GeoPoint((int) (location.getLatitude() * 1E6),
				(int) (location.getLongitude() * 1E6));

		myMapView = (MapView) findViewById(R.id.mapview);
		myMapController = myMapView.getController();

		System.out.println(gp.getLatitudeE6() * 1E6 + "--"
				+ gp.getLongitudeE6() * 1E6);
		myMapController.setCenter(gp);
		myMapController.setZoom(16);
		this.myGeoPoint = gp;
		this.myLocation = location;

		getNearestLocations();
	}

	private void getNearestLocations() {
		System.out.println("GET NEAREST LOCATIONS");
		TreeMap<Float, ArrayList<String>> cableDistanceMap = new TreeMap<Float, ArrayList<String>>();

		AppPreferences appPrefs = new AppPreferences(this);
		ArrayList<ArrayList<String>> allCables = appPrefs.getStoredCableArray();

		for (ArrayList<String> cable : allCables) {
			if (cable.size() < 5)
				continue;

			String cableAddress = cable.get(0) + ", " + cable.get(3) + ", "
					+ cable.get(4);

			GeoPoint gp = getGeoPointByAddress(cableAddress);

			if (gp != null) {
				Location cabLocation = new Location("");
				cabLocation.setLatitude(gp.getLatitudeE6());
				cabLocation.setLongitude(gp.getLongitudeE6());

				if (myLocation != null && cabLocation != null) {
					float distance = myLocation.distanceTo(cabLocation);
					if(cableDistanceMap.get(distance) == null)
						cableDistanceMap.put(distance, cable);
					else
						cableDistanceMap.put((float) (distance+0.000000001), cable);
				}
			}
		}
		
		ArrayList<Float> distanceArray = new ArrayList<Float>();
		Float cableDistance = cableDistanceMap.firstEntry().getKey();
		distanceArray.add(cableDistance);
		int cabCounter = this.cableCount;
		
		while (cabCounter >= 0) {
			distanceArray.add(cableDistanceMap.higherKey(cableDistance));
			cabCounter--;
		}
		
//		Float[] keys=new Float[cableDistanceMap.size()];   
//		cableDistanceMap.keySet().toArray(keys);  
//          
//        Arrays.sort(keys, Collections.reverseOrder());
		

//		Set<Float> keys = cableDistanceMap.keySet();
//		int counter = cableCount;

		int minLatitude = Integer.MAX_VALUE;
		int maxLatitude = Integer.MIN_VALUE;
		int minLongitude = Integer.MAX_VALUE;
		int maxLongitude = Integer.MIN_VALUE;
		
		maxLatitude = Math.max(myGeoPoint.getLatitudeE6(), maxLatitude);
		minLatitude = Math.min(myGeoPoint.getLatitudeE6(), minLatitude);
		maxLongitude = Math.max(myGeoPoint.getLongitudeE6(), maxLongitude);
		minLongitude = Math.min(myGeoPoint.getLongitudeE6(), minLongitude);
		
		
//		ArrayList<GeoPoint> overLayItems = new ArrayList<GeoPoint>();

		HashMap<String, GeoPoint> overLayItems = new HashMap<String, GeoPoint>();
		HashMap<String, ArrayList<String>> overLayItemsCables = new HashMap<String, ArrayList<String>>();
		
		// calculate mapViewZoom
		for (Float key : distanceArray) {
			System.out.println("liste: "+key);
//			if (counter <= 0)
//				break;
			System.out.println("keys: " + key);
			ArrayList<String> cable = cableDistanceMap.get(key);
			String cableAddress = cable.get(0) + ", " + cable.get(3) + ", "
					+ cable.get(4);

			GeoPoint gpToSet = getGeoPointByAddress(cableAddress);
			overLayItems.put(cable.get(1), gpToSet);
			overLayItemsCables.put(cable.get(1), cable);
			
			int lat = gpToSet.getLatitudeE6();
			int lon = gpToSet.getLongitudeE6();

			maxLatitude = Math.max(lat, maxLatitude);
			minLatitude = Math.min(lat, minLatitude);
			maxLongitude = Math.max(lon, maxLongitude);
			minLongitude = Math.min(lon, minLongitude);

//			counter--;
		}
		myMapController.zoomToSpan(Math.abs(maxLatitude - minLatitude),
				Math.abs(maxLongitude - minLongitude));
		myMapController.animateTo(new GeoPoint((maxLatitude + minLatitude) / 2,
				(maxLongitude + minLongitude) / 2));
		
		
//		List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable1 = this.getResources().getDrawable(R.drawable.pushpin);
        SitesOverlay myitemizedoverlay = new SitesOverlay(drawable1, this, null);
        OverlayItem myoverlayitem = new OverlayItem(this.myGeoPoint, "You!", "This is your current location");
        myitemizedoverlay.addOverlay(myoverlayitem);
		
		listOfOverlays = myMapView.getOverlays();
		listOfOverlays.clear();
		listOfOverlays.add(myitemizedoverlay);
		
		for(String overlayGP : overLayItems.keySet()){
	        Drawable drawable2 = this.getResources().getDrawable(R.drawable.waterskiicon);
	        SitesOverlay itemizedoverlay = new SitesOverlay(drawable2, this, overLayItemsCables.get(overlayGP));
	        OverlayItem overlayitem = new OverlayItem(overLayItems.get(overlayGP), "Error", "Cable not found");
	        itemizedoverlay.addOverlay(overlayitem);
	        
			listOfOverlays.add(itemizedoverlay);
		}
		myMapView.invalidate();
	}

	private GeoPoint getGeoPointByAddress(String cableAddress) {
		Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
		GeoPoint gp = null;
		try {
			List<Address> addresses = geoCoder.getFromLocationName(
					cableAddress, 1);
			for (Address address : addresses) {
				gp = new GeoPoint((int) (address.getLatitude() * 1E6),
						(int) (address.getLongitude() * 1E6));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return gp;
	}

	class MapOverlay extends com.google.android.maps.ItemizedOverlay<OverlayItem> {
		private GeoPoint gp;
		private boolean isMyLocation;
		private String cable;
		
		  public MapOverlay(Drawable defaultMarker) {
			    super(defaultMarker);
			    populate();
			  }

//		public MapOverlay(GeoPoint gp, boolean isMyLocation, String cable) {
//			this.gp = gp;
//			this.isMyLocation = isMyLocation;
//			this.cable = cable;
//		}

		@Override
		public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
				long when) {
			super.draw(canvas, mapView, shadow);

			// ---translate the GeoPoint to screen pixels---
			Point screenPts = new Point();
			mapView.getProjection().toPixels(gp, screenPts);
			Bitmap bmp;

			// ---add the marker---
			if(isMyLocation){
				bmp = BitmapFactory.decodeResource(getResources(),
						R.drawable.pushpin);
				canvas.drawBitmap(bmp, screenPts.x - 36, screenPts.y - 72, null);
			}else{
				bmp = BitmapFactory.decodeResource(getResources(),
						R.drawable.waterskiicon);
				canvas.drawBitmap(bmp, screenPts.x - 20, screenPts.y - 20, null);
			}
			return true;
		}
		
	    @Override
	    public boolean onTap (final GeoPoint p, final MapView mapView) {
	    	if(super.onTap(p, mapView)) {
                return true;
            }
//	        Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
//	        try {
//	            List<Address> addresses = geoCoder.getFromLocation(p.getLatitudeE6() / 1E6,
//	                        p.getLongitudeE6() / 1E6, 1);
//	            String address = "";
//	            if (addresses.size() > 0) {
//	            for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++)
//	                    address += addresses.get(0).getAddressLine(i) + "\n";
//	            }   
//	            address.cancel();
//	            address.setText(address);
//	            address.show(); 
//	        }
//	        catch (IOException e) {
//	            e.printStackTrace();
//	        }
	    	
	    	System.out.println("clicked cable: "+cable);
	        return true;
	    }

		@Override
		protected OverlayItem createItem(int i) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public int size() {
			// TODO Auto-generated method stub
			return 0;
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

}

// class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
// ImageView bmImage;
//
// public DownloadImageTask(ImageView bmImage) {
// this.bmImage = bmImage;
// }
//
// protected Bitmap doInBackground(String... urls) {
// String urldisplay = urls[0];
// Bitmap mIcon11 = null;
// try {
// InputStream in = new java.net.URL(urldisplay).openStream();
// mIcon11 = BitmapFactory.decodeStream(in);
// } catch (Exception e) {
// Log.e("Error", e.getMessage());
// e.printStackTrace();
// }
// return mIcon11;
// }
//
// protected void onPostExecute(Bitmap result) {
// bmImage.setImageBitmap(result);
// }
// }
